package com.parking.platform.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.parking.common.core.model.PageInfo;
import com.parking.common.core.model.StateData;
import com.parking.platform.dao.*;
import com.parking.platform.dto.ResourceDto;
import com.parking.platform.dto.ResourceDtos;
import com.parking.platform.dto.ShowResourceDto;
import com.parking.platform.entity.PlatformAccountRole;
import com.parking.platform.entity.PlatformResource;
import com.parking.platform.entity.PlatformRole;
import com.parking.platform.entity.PlatformRoleResource;
import com.parking.platform.exception.PlatformException;
import com.parking.platform.exception.PlatformExceptionCode;
import com.parking.platform.form.AddResourceForm;
import com.parking.platform.form.SelResourceForm;
import com.parking.platform.form.UpResourceForm;
import com.parking.platform.form.UpResourceInfoForm;
import com.parking.platform.service.PlatformResourceService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 香菜狗带
 * @since 2023年11月28日
 */
@Service
public class PlatformResourceServiceImpl extends ServiceImpl<PlatformResourceMapper, PlatformResource> implements PlatformResourceService {
    @Autowired
    private PlatformResourceMapper platformResourceMapper;
    @Autowired
    private PlatformAccountRoleMapper platformAccountRoleMapper;
    @Autowired
    private PlatformRoleMapper platformRoleMapper;
    @Autowired
    private PlatformRoleResourceMapper platformRoleResourceMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private PlatformAccountMapper platformAccountMapper;


    /**判断用户身份。根据身份角色，返回角色菜单
     * 查询管理员权限菜单
     * 参数：
     * 令牌：authorization
     * 返回ResourceDto
     *
     */
    @Override
    public List<ResourceDto> platformResourceAll(Integer platformId) {
        //获取当前用户Id的角色
        QueryWrapper<PlatformAccountRole> accountRoleWrapper = new QueryWrapper<>();
        accountRoleWrapper.eq("platform_account_id",platformId);
        PlatformAccountRole accountRole = platformAccountRoleMapper.selectOne(accountRoleWrapper);
        if (accountRole==null) {
            throw new PlatformException(PlatformExceptionCode.FAILED_IS_NOT_ROLE);
        }
        //角色平台信息
        PlatformRole platformRole = platformRoleMapper.selectById(accountRole.getPlatformRoleId());
        if (platformRole.getPlatformRoleState()!= StateData.PLATFORM_ROLE_STATE_ENABLE) {
            throw new PlatformException(PlatformExceptionCode.FAILED_ROLE_STATE);
        }
        //获取全部权限菜单
        QueryWrapper<PlatformRoleResource> roleResourceWrapper = new QueryWrapper<>();
        roleResourceWrapper.eq("platform_role_id", platformRole.getPlatformRoleId());
        // 获取角色关联资源列表
        List<PlatformRoleResource> roleResourceList = platformRoleResourceMapper.selectList(roleResourceWrapper);
        if (roleResourceList == null || roleResourceList.isEmpty()) {
            // 如果列表为空，则直接返回空列表
            return new ArrayList<>();
        }
        // 提取资源 ID 列表
        List<Integer> resourceIdList = roleResourceList.stream()
                .map(PlatformRoleResource::getPlatformResourceId)
                .collect(Collectors.toList());
        List<PlatformResource> resources = platformResourceMapper.selectBatchIds(resourceIdList);
        ArrayList<ResourceDto> list = new ArrayList<>();
        for (PlatformResource resource : resources) {
            if (resource.getPlatformResourceParent()== StateData.PLATFORM_RESOURCE_ID) {
                ResourceDto resourceDto = BeanUtil.toBean(resource, ResourceDto.class);
                list.add(resourceDto);
                //子节点
                this.childResource(resourceDto);
            }
        }
        return list;
    }
    /**
     * 查询管理员权限菜单
     * 参数：
     *
     *  pageNum:当前页数
     *  pageSize:当前条数
     *  resourceName:资源名称
     * 返回ResourceDto
     *
     */
    @Override
    public PageInfo showResourceAll(SelResourceForm form) {
        Page<PlatformResource> page = new Page<>(form.getPageNum()!=null?form.getPageNum():1, form.getPageSize()!=null?form.getPageSize():8);
        QueryWrapper<PlatformResource> wrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(form.getResourceName())) {
            wrapper.like("platform_resource_name",form.getResourceName());
        }
        platformResourceMapper.selectPage(page,wrapper);
        List<ShowResourceDto> dtos = BeanUtil.copyToList(page.getRecords(), ShowResourceDto.class);
        for (ShowResourceDto dto : dtos) {
            if (dto.getPlatformResourceParent()!=0) {
                dto.setPlatformParentName(platformResourceMapper.selectById(dto.getPlatformResourceParent()).getPlatformResourceName());
            }else {
                dto.setPlatformParentName("一级菜单");
            }
            if (ObjectUtil.isNotEmpty( dto.getPlatformResourceAddPerson())) {
                dto.setPlatformResourceAddPersonName(platformAccountMapper.selectById(dto.getPlatformResourceAddPerson()).getPlatformAccount());
            }
            if (ObjectUtil.isNotEmpty( dto.getPlatformResourceUpdatePerson())) {
                dto.setPlatformResourceUpdatePersonName(platformAccountMapper.selectById(dto.getPlatformResourceUpdatePerson()).getPlatformAccount());
            }
    }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setRecords(dtos);
        return pageInfo;
    }



    /**
     * 修改管理员权限
     * 参数：
     * platformResourceId:平台资源id
     * platformResourceName:平台资源名称
     * platformResourceParent:平台资源父节点
     * platformResourceRouter:平台资源路由地址
     *
     * */
    @Override
    @Transactional
    public void upResourceData(UpResourceForm form, Integer platformId) {
        PlatformResource resource = platformResourceMapper.selectById(form.getPlatformResourceId());
        if (resource==null) {
            throw new PlatformException(PlatformExceptionCode.FAILED_RESOURCE_EXIST);
        }
        if (resource.getPlatformResourceRouter().equals(form.getPlatformResourceRouter())&&
        resource.getPlatformResourceName().equals(form.getPlatformResourceName())) {
            throw new PlatformException(PlatformExceptionCode.FAILED_RESOURCE_REPEAT);
        }
        resource.setPlatformResourceParent(form.getPlatformResourceParent());
        resource.setPlatformResourceRouter(form.getPlatformResourceRouter());
        resource.setPlatformResourceName(form.getPlatformResourceName());
        platformResourceMapper.updateById(resource);

        resource.setPlatformResourceUpdatePerson(String.valueOf(platformId));
        resource.setPlatformResourceUpdateTime(LocalDateTime.now());
        HashMap<String, Object> map = new HashMap<>();
        map.put("platformResource",resource);
        rabbitTemplate.convertAndSend("upResourceData",map);

    }
    /**
     * 添加权限资源
     * 参数：
     * platformResourceName:平台资源名称
     * platformResourceParent:平台资源父节点
     * platformResourceRouter:平台资源路由地址
     *
     * */
    @Transactional
    @Override
    public void addResourceData(AddResourceForm form, Integer platformId) {
        QueryWrapper<PlatformResource> wrapper = new QueryWrapper<>();
        wrapper.eq("platform_resource_name",form.getPlatformResourceName());
        wrapper.eq("platform_resource_router",form.getPlatformResourceRouter());
        PlatformResource resource = platformResourceMapper.selectOne(wrapper);
        if (resource!=null) {
            throw new PlatformException(PlatformExceptionCode.FAILED_RESOURCE_REPEAT);
        }
//        QueryWrapper<PlatformResource> wrapper2 = new QueryWrapper<>();
//        wrapper2.eq("platform_resource_id",form.getPlatformResourceParent());
//        PlatformResource platformResource = platformResourceMapper.selectOne(wrapper2);
//        if (platformResource==null) {
//            throw new PlatformException(PlatformExceptionCode.FAILED_RESOURCE_PARENT_EXIST);
//        }
        PlatformResource addResource = BeanUtil.toBean(form, PlatformResource.class);
        platformResourceMapper.insert(addResource);
        addResource.setPlatformResourceAddPerson(String.valueOf(platformId));
        addResource.setPlatformResourceAddTime(LocalDateTime.now());
        HashMap<String, Object> map = new HashMap<>();
        map.put("platformResource",addResource);
        rabbitTemplate.convertAndSend("addResourceData",map);

    }
    /**
     * 查询管理员权限菜单
     * 参数：
     * 名称：platformResourceName
     * 返回ResourceDto
     * 返回前端的菜单参数对象
     * 资源Id:platformResourceId
     * 资源名称:platformResourceName
     * 资源路由名称:platformResourceRouter
     * 父节点ID：platformResourceParent
     * 二级菜单:child
     *
     */
    @Override
    public ResourceDtos findResourceAll(String platformResourceName, Integer platformRoleId) {
        QueryWrapper<PlatformResource> wrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(platformResourceName)) {
            wrapper.eq("platform_resource_name", platformResourceName);
        }
        List<PlatformResource> list = platformResourceMapper.selectList(wrapper);
        ArrayList<ResourceDto> resourcesList = new ArrayList<>();
        for (PlatformResource resource : list) {
            if (resource.getPlatformResourceParent().equals(StateData.PLATFORM_RESOURCE_ID)) {
                ResourceDto resourceDto = BeanUtil.toBean(resource, ResourceDto.class);
                resourceDto.setPlatformResourceId(resource.getPlatformResourceId());
                resourcesList.add(resourceDto);
                this.childResource(resourceDto);
            }
        }
        QueryWrapper<PlatformRoleResource> resourceWrapper = new QueryWrapper<>();
        resourceWrapper.eq("platform_role_id", platformRoleId);
        List<PlatformRoleResource> roleResourceList = platformRoleResourceMapper.selectList(resourceWrapper);
        List<Integer> resourceIds = roleResourceList.stream().map(PlatformRoleResource::getPlatformResourceId).collect(Collectors.toList());
        List<Integer> ids = new ArrayList<>();
        for (ResourceDto resourceDto : resourcesList) {
            if (resourceIds.contains(resourceDto.getPlatformResourceId())){
                resourceDto.setChecked(true);
                setChildrenChecked(resourceDto.getChild(),resourceIds,ids);
            }else {
                resourceDto.setChecked(false);
            }
        }
        ResourceDtos rd = new ResourceDtos();
        rd.setIds(ids);
        rd.setRds(resourcesList);
        return rd;


    }
    /**
     * 查询全部父节点
     * 无参数：
     *
     * */
    @Override
    public List<ResourceDto> ParentResourceAll() {
        QueryWrapper<PlatformResource> wrapper = new QueryWrapper<>();
        wrapper.eq("platform_resource_parent",StateData.PLATFORM_RESOURCE_ID);
        List<PlatformResource> list = platformResourceMapper.selectList(wrapper);
        List<ResourceDto> resourceDtos = BeanUtil.copyToList(list, ResourceDto.class);
        return resourceDtos;
    }
    /**
     * 修改资源信息
     * 参数：
     *平台资源父节点：platformResourceParent
     * 平台资源id：platformResourceId
     * 平台资源父节点：platformResourceParent
     *  资源名称:platformResourceName
     * */
    @Override
    @Transactional
    public void upResourceInfo(UpResourceInfoForm form, Integer platformId) {
        PlatformResource resource = platformResourceMapper.selectById(form.getPlatformResourceId());
        if (resource==null) {
            throw new PlatformException(PlatformExceptionCode.FAILED_RESOURCE_EXIST);
        }
        resource.setPlatformResourceName(form.getPlatformResourceName());
        resource.setPlatformResourceRouter(form.getPlatformResourceRouter());
        resource.setPlatformResourceParent(form.getPlatformResourceParent());
        platformResourceMapper.updateById(resource);
        resource.setPlatformResourceUpdateTime(LocalDateTime.now());
        resource.setPlatformResourceUpdatePerson(String.valueOf(platformId));
        HashMap<String, Object> map = new HashMap<>();
        map.put("platformResource",resource);
        rabbitTemplate.convertAndSend("upResourceInfo",map);

    }

    @Override
    public List<String> findResourceRouter(Integer platformId) {
        QueryWrapper<PlatformAccountRole> wrapper = new QueryWrapper<>();
        wrapper.eq("platform_account_id",platformId);
        PlatformAccountRole accountRole = platformAccountRoleMapper.selectOne(wrapper);
        QueryWrapper<PlatformRoleResource> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("platform_role_id",accountRole.getPlatformRoleId());
        List<PlatformRoleResource> resources = platformRoleResourceMapper.selectList(queryWrapper);
        System.out.println(resources+"参数");
        List<Integer> roleResourceIds = resources.stream().map(PlatformRoleResource::getPlatformResourceId).collect(Collectors.toList());
        List<PlatformResource> list = platformResourceMapper.selectBatchIds(roleResourceIds);
        List<String> collect = list.stream().map(PlatformResource::getPlatformResourceRouter).collect(Collectors.toList());
        return collect;
    }

    /**
     * 查询二级菜单
     * */
    public void childResource(ResourceDto resourceDto){
        QueryWrapper<PlatformResource> wrapper = new QueryWrapper<>();
        wrapper.eq("platform_resource_parent",resourceDto.getPlatformResourceId());
        List<PlatformResource> list = platformResourceMapper.selectList(wrapper);
        if(list!=null&&list.size()!=0){
            for (PlatformResource resource : list) {
                ResourceDto dto = BeanUtil.toBean(resource, ResourceDto.class);
                dto.setPlatformResourceId(resource.getPlatformResourceId());
                resourceDto.getChild().add(dto);
                this.childResource(dto);
            }
        }
    }

    public void setChildrenChecked(List<ResourceDto> resourceDto,List<Integer>resourcesIds,List<Integer> ids){
        if (ObjectUtil.isNotEmpty(resourceDto)){
            for (ResourceDto dto : resourceDto) {
                if (resourcesIds.contains(dto.getPlatformResourceId())){
                    dto.setChecked(true);
                    ids.add(dto.getPlatformResourceId());
                }else {
                    dto.setChecked(false);
                }
                setChildrenChecked(dto.getChild(),resourcesIds,ids);
            }
        }
    }
}
